/**
 * @brief    瞬态分析测试
 *
 * @version  0.1
 * @author   wjw
 * @date     2025.03.11
 *         _
 *     ___| |__   ___ _ __   __ _  ___  _ __   __ _
 *    / __| '_ \ / _ \ '_ \ / _` |/ _ \| '_ \ / _` |
 *    \__ \ | | |  __/ | | | (_| | (_) | | | | (_| |
 *    |___/_| |_|\___|_| |_|\__, |\___/|_| |_|\__, |
 *                          |___/             |___/
 * @copyright (c) 2025 by 神工仿真, All Rights Reserved.
 */
#pragma once
#include "gtest/gtest.h"

#include "SGFem/Task/Kernel/MModel.h"
#include "SGFem/Task/Solver/TransientDirectSolver.h"

using SG::DataStructure::Common::Status;
using SG::DataStructure::FEM::Project;
using namespace SG::DBManager;

extern std::shared_ptr<DBServiceFactory> DB_SERVICEFACTORY;

struct TransientDirectAnalysisTestData
{
    std::string         m_inputFile;    ///< 输入文件名称
    std::vector<double> m_modalTarget;  ///< Nastran响应结果
    SG::Algebra::Real_t m_error;        ///< 误差上限
};

class TransientDirectTest : public ::testing::TestWithParam<TransientDirectAnalysisTestData>
{
  protected:
    void SetUp () override
    {
        modelPath = getTestDataPath ("SGFem/ModalAnalysis/");
    }

    void TearDown () override
    {
        DB_SERVICEFACTORY->ClearDatabase ();
    }
    std::string modelPath;  ///< 输入模型文件路径
};

TEST_P (TransientDirectTest, ComputeResponseAsExpect)
{
    // Input
    auto para = GetParam ();
    Project project;
    project.m_modelFilePath = modelPath;
    project.m_modelFileName = para.m_inputFile;
    auto posi               = para.m_inputFile.find ('.');
    project.m_jobName       = para.m_inputFile.substr (0, posi);

    DB_SERVICEFACTORY->ClearDatabase ();
    SG::Import::SGImporter importer (DB_SERVICEFACTORY);
    auto                   status = importer.Import (project.m_modelFilePath + project.m_modelFileName);
    ASSERT_EQ (status, Status::STATUS_Success);

    auto       subcaseIds = DB_SERVICEFACTORY->get<ISubcaseService> ()->GetAllSubcaseID (); // 获取模型中所有的subCase
    const auto subcaseId  = subcaseIds[0];

    // Test data
    TransientDirectSolver solver;
    solver.Solve (DB_SERVICEFACTORY, project, subcaseId);

    Kernel::MModel                  ModelTest (SG::DataStructure::FEM::SOLType::SOL_SEDTRAN, DB_SERVICEFACTORY);
    auto                            paraS = DB_SERVICEFACTORY->get<ISubcaseService> ()->FindSubCase (subcaseId);
    SG::DataStructure::FEM::Subcase subcase (paraS);

    const auto                                   tStepId = subcase.GetTSTEPId ();
    std::vector<SG::DataStructure::Common::Real> t;
    std::vector<SG::DataStructure::Common::Real> tOut;
    ModelTest.QueryTimeStep (tStepId, t, tOut);

    SG::Algebra::Vec_t  V;
    std::vector<SG::DataStructure::Common::Real> modalTest;
    for (auto &&ti : t)
    {
        ModelTest.GetDisplacement (subcaseId, ti, _OUT V);
        modalTest.push_back (V (269));
    }
    
    // Target data
    const auto modalTarget = para.m_modalTarget;

    // Check 计算相对误差
    SG::DataStructure::Common::Real numerator_norm   = 0.0;
    SG::DataStructure::Common::Real denominator_norm = 0.0;
    SG::DataStructure::Common::Real diff;
    for (size_t i = 0; i < modalTest.size (); ++i)
    {
        diff = modalTest[i] - modalTarget[i];
        numerator_norm += diff * diff;
        denominator_norm += modalTarget[i] * modalTarget[i];
    }
    numerator_norm        = std::sqrt (numerator_norm);
    denominator_norm      = std::sqrt (denominator_norm);
    SG::DataStructure::Common::Real relative_error = numerator_norm / denominator_norm;
    ASSERT_LE (relative_error, para.m_error);
};
std::vector<SG::DataStructure::Common::Real> modalTargetDirect = {
    0.000000E+00,  3.598265E-08,  1.598010E-07,  4.417047E-07,  9.345405E-07,  1.693891E-06,  2.776245E-06,  4.239961E-06,  6.146095E-06,
    8.558344E-06,  1.154242E-05,  1.516554E-05,  1.949583E-05,  2.460176E-05,  3.055166E-05,  3.741346E-05,  4.525446E-05,  5.414105E-05,
    6.413735E-05,  7.530559E-05,  8.770628E-05,  1.013992E-04,  1.164425E-04,  1.328929E-04,  1.508053E-04,  1.702327E-04,  1.912265E-04,
    2.138359E-04,  2.381072E-04,  2.640845E-04,  2.918093E-04,  3.213205E-04,  3.526555E-04,  3.858500E-04,  4.209387E-04,  4.579546E-04,
    4.969288E-04,  5.378922E-04,  5.808767E-04,  6.259144E-04,  6.730359E-04,  7.222701E-04,  7.736441E-04,  8.271838E-04,  8.829137E-04,
    9.408577E-04,  1.001039E-03,  1.063481E-03,  1.128207E-03,  1.195241E-03,  1.264606E-03,  1.336326E-03,  1.410424E-03,  1.486919E-03,
    1.565831E-03,  1.647176E-03,  1.730975E-03,  1.817241E-03,  1.905987E-03,  1.997222E-03,  2.090949E-03,  2.187172E-03,  2.285888E-03,
    2.387096E-03,  2.490790E-03,  2.596965E-03,  2.705615E-03,  2.816733E-03,  2.930314E-03,  3.046349E-03,  3.164827E-03,  3.285736E-03,
    3.409060E-03,  3.534789E-03,  3.662910E-03,  3.793407E-03,  3.926263E-03,  4.061457E-03,  4.198966E-03,  4.338766E-03,  4.480829E-03,
    4.625128E-03,  4.771637E-03,  4.920327E-03,  5.071172E-03,  5.224142E-03,  5.379213E-03,  5.536352E-03,  5.695527E-03,  5.856700E-03,
    6.019840E-03,  6.184911E-03,  6.351880E-03,  6.520708E-03,  6.691354E-03,  6.863778E-03,  7.037934E-03,  7.213776E-03,  7.391256E-03,
    7.570327E-03,  7.750941E-03,  7.933049E-03,  8.116602E-03,  8.301554E-03,  8.487857E-03,  8.675454E-03,  8.864292E-03,  9.054315E-03,
    9.245475E-03,  9.437719E-03,  9.631001E-03,  9.825272E-03,  1.002048E-02,  1.021659E-02,  1.041354E-02,  1.061129E-02,  1.080979E-02,
    1.100901E-02,  1.120890E-02,  1.140941E-02,  1.161051E-02,  1.181215E-02,  1.201429E-02,  1.221687E-02,  1.241985E-02,  1.262318E-02,
    1.282681E-02,  1.303069E-02,  1.323480E-02,  1.343908E-02,  1.364350E-02,  1.384801E-02,  1.405259E-02,  1.425719E-02,  1.446179E-02,
    1.466634E-02,  1.487081E-02,  1.507517E-02,  1.527938E-02,  1.548341E-02,  1.568722E-02,  1.589074E-02,  1.609394E-02,  1.629678E-02,
    1.649922E-02,  1.670123E-02,  1.690277E-02,  1.710382E-02,  1.730435E-02,  1.750434E-02,  1.770377E-02,  1.790262E-02,  1.810086E-02,
    1.829849E-02,  1.849548E-02,  1.869182E-02,  1.888748E-02,  1.908243E-02,  1.927665E-02,  1.947010E-02,  1.966273E-02,  1.985454E-02,
    2.004550E-02,  2.023559E-02,  2.042479E-02,  2.061309E-02,  2.080048E-02,  2.098696E-02,  2.117252E-02,  2.135716E-02,  2.154087E-02,
    2.172365E-02,  2.190549E-02,  2.208640E-02,  2.226635E-02,  2.244532E-02,  2.262331E-02,  2.280028E-02,  2.297622E-02,  2.315113E-02,
    2.332501E-02,  2.349784E-02,  2.366965E-02,  2.384043E-02,  2.401021E-02,  2.417899E-02,  2.434679E-02,  2.451363E-02,  2.467952E-02,
    2.484448E-02,  2.500853E-02,  2.517167E-02,  2.533390E-02,  2.549523E-02,  2.565564E-02,  2.581514E-02,  2.597373E-02,  2.613143E-02,
    2.628825E-02,  2.644420E-02,  2.659931E-02,  2.675359E-02,  2.690707E-02,  2.705977E-02,  2.721172E-02,  2.736294E-02,  2.751346E-02,
    2.766329E-02,  2.781246E-02,  2.796096E-02,  2.810881E-02,  2.825601E-02,  2.840256E-02,  2.854847E-02,  2.869375E-02,  2.883842E-02,
    2.898249E-02,  2.912598E-02,  2.926891E-02,  2.941130E-02,  2.955317E-02,  2.969455E-02,  2.983546E-02,  2.997592E-02,  3.011595E-02,
    3.025556E-02,  3.039476E-02,  3.053356E-02,  3.067197E-02,  3.080998E-02,  3.094760E-02,  3.108484E-02,  3.122170E-02,  3.135818E-02,
    3.149431E-02,  3.163008E-02,  3.176552E-02,  3.190063E-02,  3.203541E-02,  3.216990E-02,  3.230408E-02,  3.243798E-02,  3.257160E-02,
    3.270493E-02,  3.283800E-02,  3.297080E-02,  3.310332E-02,  3.323556E-02,  3.336754E-02,  3.349923E-02,  3.363064E-02,  3.376178E-02,
    3.389263E-02,  3.402320E-02,  3.415350E-02,  3.428352E-02,  3.441325E-02,  3.454271E-02,  3.467188E-02,  3.480078E-02,  3.492939E-02,
    3.505772E-02,  3.518577E-02,  3.531352E-02,  3.544097E-02,  3.556812E-02,  3.569496E-02,  3.582147E-02,  3.594764E-02,  3.607345E-02,
    3.619890E-02,  3.632396E-02,  3.644863E-02,  3.657288E-02,  3.669670E-02,  3.682007E-02,  3.694298E-02,  3.706541E-02,  3.718735E-02,
    3.730879E-02,  3.742972E-02,  3.755012E-02,  3.766999E-02,  3.778929E-02,  3.790800E-02,  3.802611E-02,  3.814357E-02,  3.826036E-02,
    3.837646E-02,  3.849183E-02,  3.860644E-02,  3.872027E-02,  3.883326E-02,  3.894541E-02,  3.905669E-02,  3.916707E-02,  3.927654E-02,
    3.938508E-02,  3.949268E-02,  3.959930E-02,  3.970494E-02,  3.980955E-02,  3.991310E-02,  4.001556E-02,  4.011689E-02,  4.021705E-02,
    4.031601E-02,  4.041373E-02,  4.051016E-02,  4.060526E-02,  4.069901E-02,  4.079137E-02,  4.088231E-02,  4.097182E-02,  4.105989E-02,
    4.114650E-02,  4.123162E-02,  4.131524E-02,  4.139733E-02,  4.147785E-02,  4.155678E-02,  4.163408E-02,  4.170972E-02,  4.178365E-02,
    4.185585E-02,  4.192626E-02,  4.199487E-02,  4.206163E-02,  4.212651E-02,  4.218949E-02,  4.225057E-02,  4.230972E-02,  4.236695E-02,
    4.242223E-02,  4.247555E-02,  4.252689E-02,  4.257624E-02,  4.262356E-02,  4.266882E-02,  4.271200E-02,  4.275306E-02,  4.279197E-02,
    4.282871E-02,  4.286323E-02,  4.289551E-02,  4.292553E-02,  4.295325E-02,  4.297868E-02,  4.300181E-02,  4.302263E-02,  4.304113E-02,
    4.305731E-02,  4.307115E-02,  4.308265E-02,  4.309178E-02,  4.309852E-02,  4.310285E-02,  4.310475E-02,  4.310419E-02,  4.310116E-02,
    4.309563E-02,  4.308757E-02,  4.307696E-02,  4.306379E-02,  4.304806E-02,  4.302976E-02,  4.300889E-02,  4.298545E-02,  4.295945E-02,
    4.293087E-02,  4.289972E-02,  4.286598E-02,  4.282964E-02,  4.279071E-02,  4.274916E-02,  4.270498E-02,  4.265817E-02,  4.260870E-02,
    4.255657E-02,  4.250176E-02,  4.244426E-02,  4.238409E-02,  4.232123E-02,  4.225571E-02,  4.218752E-02,  4.211667E-02,  4.204317E-02,
    4.196702E-02,  4.188822E-02,  4.180679E-02,  4.172271E-02,  4.163601E-02,  4.154666E-02,  4.145468E-02,  4.136007E-02,  4.126281E-02,
    4.116292E-02,  4.106039E-02,  4.095523E-02,  4.084744E-02,  4.073705E-02,  4.062406E-02,  4.050848E-02,  4.039032E-02,  4.026959E-02,
    4.014630E-02,  4.002047E-02,  3.989210E-02,  3.976122E-02,  3.962781E-02,  3.949190E-02,  3.935349E-02,  3.921258E-02,  3.906918E-02,
    3.892330E-02,  3.877494E-02,  3.862412E-02,  3.847083E-02,  3.831511E-02,  3.815696E-02,  3.799637E-02,  3.783338E-02,  3.766799E-02,
    3.750022E-02,  3.733007E-02,  3.715758E-02,  3.698274E-02,  3.680557E-02,  3.662609E-02,  3.644430E-02,  3.626021E-02,  3.607383E-02,
    3.588518E-02,  3.569426E-02,  3.550109E-02,  3.530568E-02,  3.510803E-02,  3.490815E-02,  3.470606E-02,  3.450178E-02,  3.429532E-02,
    3.408669E-02,  3.387592E-02,  3.366302E-02,  3.344801E-02,  3.323092E-02,  3.301174E-02,  3.279051E-02,  3.256723E-02,  3.234191E-02,
    3.211458E-02,  3.188525E-02,  3.165393E-02,  3.142063E-02,  3.118536E-02,  3.094815E-02,  3.070901E-02,  3.046796E-02,  3.022501E-02,
    2.998020E-02,  2.973355E-02,  2.948507E-02,  2.923480E-02,  2.898275E-02,  2.872895E-02,  2.847341E-02,  2.821616E-02,  2.795722E-02,
    2.769660E-02,  2.743433E-02,  2.717042E-02,  2.690488E-02,  2.663775E-02,  2.636903E-02,  2.609876E-02,  2.582695E-02,  2.555363E-02,
    2.527883E-02,  2.500258E-02,  2.472489E-02,  2.444580E-02,  2.416534E-02,  2.388353E-02,  2.360039E-02,  2.331595E-02,  2.303024E-02,
    2.274328E-02,  2.245509E-02,  2.216570E-02,  2.187512E-02,  2.158339E-02,  2.129053E-02,  2.099656E-02,  2.070152E-02,  2.040544E-02,
    2.010834E-02,  1.981026E-02,  1.951123E-02,  1.921128E-02,  1.891045E-02,  1.860875E-02,  1.830620E-02,  1.800276E-02,  1.769841E-02,
    1.739311E-02,  1.708686E-02,  1.677961E-02,  1.647134E-02,  1.616203E-02,  1.585165E-02,  1.554016E-02,  1.522752E-02,  1.491372E-02,
    1.459871E-02,  1.428246E-02,  1.396494E-02,  1.364613E-02,  1.332600E-02,  1.300452E-02,  1.268167E-02,  1.235743E-02,  1.203178E-02,
    1.170471E-02,  1.137618E-02,  1.104620E-02,  1.071475E-02,  1.038181E-02,  1.004737E-02,  9.711427E-03,  9.373976E-03,  9.035014E-03,
    8.694544E-03,  8.352569E-03,  8.009097E-03,  7.664137E-03,  7.317699E-03,  6.969796E-03,  6.620440E-03,  6.269644E-03,  5.917421E-03,
    5.563786E-03,  5.208753E-03,  4.852335E-03,  4.494548E-03,  4.135405E-03,  3.774922E-03,  3.413113E-03,  3.049993E-03,  2.685578E-03,
    2.319884E-03,  1.952928E-03,  1.584728E-03,  1.215303E-03,  8.446724E-04,  4.728584E-04,  9.988434E-05,  -2.742249E-04, -6.494428E-04,
    -1.025741E-03, -1.403090E-03, -1.781459E-03, -2.160815E-03, -2.541123E-03, -2.922350E-03, -3.304458E-03, -3.687411E-03, -4.071169E-03,
    -4.455692E-03, -4.840941E-03, -5.226872E-03, -5.613443E-03, -6.000610E-03, -6.388329E-03, -6.776553E-03, -7.165236E-03, -7.554331E-03,
    -7.943791E-03, -8.333568E-03, -8.723614E-03, -9.113880E-03, -9.504317E-03, -9.894877E-03, -1.028551E-02, -1.067617E-02, -1.106680E-02,
    -1.145735E-02, -1.184779E-02, -1.223804E-02, -1.262807E-02, -1.301783E-02, -1.340725E-02, -1.379630E-02, -1.418491E-02, -1.457303E-02,
    -1.496062E-02, -1.534760E-02, -1.573394E-02, -1.611958E-02, -1.650445E-02, -1.688851E-02, -1.727169E-02
};
SG::Algebra::Real_t errorDirect = 9.58e-08;
INSTANTIATE_TEST_CASE_P (DirectTransientAnalysis,
                         TransientDirectTest,
                         testing::Values (TransientDirectAnalysisTestData{ "DirectTransientModel.bdf", modalTargetDirect, errorDirect }));
